﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace VBAConvertor.Parsers
{
    public class DimParser : ILineParser
    {
        private static readonly Regex VarPattern =
            new Regex(
                @"(?<var>[a-zA-Z_\$\d]+(\(\))?)((\s)+As(\s)+(?<type>[\w]+)((\s)+\*(\s)+(?<arrayLen>\d+))?)?",
                RegexOptions.Compiled | RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase | RegexOptions.Singleline);

        public string Parse(Stack<ParseStatus> statuses, string lineContent, LinesReader reader, out bool success, ref bool lineClosed)
        {
            success = lineContent.StartsWith("Dim ");
            if (!success) return lineContent;
            if (lineClosed)
            {
                throw new Exception();
            }
            lineClosed = true;
            var defs = lineContent.Remove(0, "Dim ".Length).Trim();
            
            switch (statuses.Peek().CurrentState)
            {
                case State.ClassDef:
                    {
                        var variables = (from Match varMatch in VarPattern.Matches(defs)
                                         select varMatch).ToArray();
                        return DefineField(variables);
                    }
                default:
                    return ParserHelper.GetVarDefs(defs, ";") + ";";
            }
        }

        private string DefineField(Match[] variables)
        {
            var cSharpLine = new StringBuilder();
            var type = "dynamic";

            for (int i = 0; i < variables.Length; i++)
            {
                var match = variables[i];
                cSharpLine.Append("private ");

                if (!string.IsNullOrEmpty(match.Groups["type"].Value))
                {
                    type = ParserHelper.AdjustType(match.Groups["type"].Value);
                }

                cSharpLine.Append(type);
                if (!string.IsNullOrEmpty(match.Groups["arrayLen"].Value))
                {
                    cSharpLine.Append("[]");
                }
                cSharpLine.Append(" ");

                cSharpLine.Append(match.Groups["var"].Value);
                cSharpLine.AppendLine(";");
            }

            return cSharpLine.ToString();
        }
    }
}
